package com.zscat.mallplus.center.service.impl;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.Date;
import java.util.Map;
import java.util.TreeMap;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zscat.mallplus.center.entity.CenterItem;
import com.zscat.mallplus.center.entity.CenterJifen;
import com.zscat.mallplus.center.entity.CenterOrderRecharge;
import com.zscat.mallplus.center.mapper.CenterOrderRechargeMapper;
import com.zscat.mallplus.center.service.ICenterItemService;
import com.zscat.mallplus.center.service.ICenterJifenService;
import com.zscat.mallplus.center.service.ICenterOrderRechargeService;
import com.zscat.mallplus.controller.ApiBaseAction;
import com.zscat.mallplus.enums.AllEnum;
import com.zscat.mallplus.enums.OrderStatus;
import com.zscat.mallplus.exception.ApiMallPlusException;
import com.zscat.mallplus.oms.entity.OmsOrder;
import com.zscat.mallplus.oms.entity.OmsOrderOperateHistory;
import com.zscat.mallplus.oms.entity.OmsPayments;
import com.zscat.mallplus.oms.service.IOmsOrderOperateHistoryService;
import com.zscat.mallplus.sys.entity.SysSystemSetting;
import com.zscat.mallplus.sys.mapper.SysSystemSettingMapper;
import com.zscat.mallplus.ums.entity.UmsMember;
import com.zscat.mallplus.ums.entity.UmsMemberBlanceLog;
import com.zscat.mallplus.ums.service.IUmsMemberBlanceLogService;
import com.zscat.mallplus.ums.service.IUmsMemberService;
import com.zscat.mallplus.util.CharUtil;
import com.zscat.mallplus.util.DateUtils;
import com.zscat.mallplus.util.MapUtils;
import com.zscat.mallplus.util.XmlUtil;
import com.zscat.mallplus.util.applet.WechatRefundApiResult;
import com.zscat.mallplus.util.applet.WechatUtil;
import com.zscat.mallplus.utils.CommonResult;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
public class CenterOrderRechargeServiceImpl implements ICenterOrderRechargeService {
	@Autowired
	private CenterOrderRechargeMapper centerOrderRechargeMapper;
	@Autowired
	private IUmsMemberService memberService;
	@Autowired
	private SysSystemSettingMapper settingMapper;
	@Autowired
	private IOmsOrderOperateHistoryService orderOperateHistoryService;
	@Autowired
	private ICenterJifenService centerJifenService;
	@Autowired
	private ICenterItemService centerItemService;
	@Autowired
	private IUmsMemberBlanceLogService blanceLogService;

	String tradeType = "JSAPI";
	String uniformorder = "https://api.mch.weixin.qq.com/pay/unifiedorder";

	@Override
	public Object add(CenterOrderRecharge centerOrderRecharge) {
		centerOrderRecharge.setCreateTime(new Date());
		centerOrderRecharge.setStatus(OrderStatus.INIT.getValue());
		centerOrderRecharge.setStoreId(0);
		centerOrderRecharge.setOrderSn(generateOrderSn(centerOrderRecharge));
		centerOrderRechargeMapper.insert(centerOrderRecharge);
		return createOrder(centerOrderRecharge.getId(), 5);
	}

	/**
	 * 生成18位订单编号:8位日期+2位平台号码+2位支付方式+6位以上自增id
	 */
	private String generateOrderSn(CenterOrderRecharge centerOrderRecharge) {
		StringBuilder sb = new StringBuilder();
		sb.append(System.currentTimeMillis());
		sb.append(String.format("%02d", centerOrderRecharge.getSourceType()));
		sb.append(String.format("%02d", centerOrderRecharge.getPayType()));
		sb.append(centerOrderRecharge.getMemberId());
		return sb.toString();
	}

	@Override
	public Object createOrder(Long orderId, Integer appIdsource) {
		UmsMember user = memberService.getNewCurrentMember();
		CenterOrderRecharge orderInfo = centerOrderRechargeMapper.selectById(orderId);
		OmsPayments appletSet = memberService.getSysAppletSet(appIdsource);
		if (null == appletSet) {
			throw new ApiMallPlusException("没有设置支付配置");
		}

		if (null == orderInfo) {
			return ApiBaseAction.toResponsObject(400, "订单已取消", "");
		}

		if (orderInfo.getStatus() == OrderStatus.CLOSED.getValue()) {
			return ApiBaseAction.toResponsObject(400, "订单已关闭，请不要重复操作", "");
		}
		String nonceStr = CharUtil.getRandomString(32);
		SysSystemSetting setting = settingMapper.selectById(1);
		String notifyUrl = setting.getSiteUrl().concat("/center/order/recharge/notify");
//		String refundNotifyUrl = setting.getSiteUrl().concat("/api/api/wxPay/refundNotify");
		// https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=7_7&index=3
		Map<Object, Object> resultObj = new TreeMap<Object, Object>();
		ApiBaseAction apiBaseAction = new ApiBaseAction();
		try {
			Map<Object, Object> parame = new TreeMap<Object, Object>();
			// 小程序ID
			parame.put("appid", appletSet.getAppId());
			// 商户号
			parame.put("mch_id", appletSet.getMchId());
			// 生成随机字符串
			String randomStr = CharUtil.getRandomNum(18).toUpperCase();
			// 随机字符串
			parame.put("nonce_str", randomStr);
			// 商户订单号
			parame.put("out_trade_no", orderInfo.getOrderSn());
			// 商品描述
			parame.put("body", "余额充值");
			// 支付金额
			parame.put("total_fee", orderInfo.getPayAmount().multiply(new BigDecimal(100)).intValue());
			// 回调地址
			parame.put("notify_url", notifyUrl);
			// 交易类型APP
			parame.put("trade_type", tradeType);
//			parame.put("spbill_create_ip", apiBaseAction.getClientIp());
			parame.put("openid", user.getWeixinOpenid());
			String sign = WechatUtil.arraySign(parame, appletSet.getPartnerKey());
			// 数字签证
			parame.put("sign", sign);
			String xml = MapUtils.convertMap2Xml(parame);
			log.info("xml:" + xml);
			Map<String, Object> resultUn = XmlUtil.xmlStrToMap(WechatUtil.requestOnce(uniformorder, xml));
			// 响应报文
			String return_code = MapUtils.getString("return_code", resultUn);
			String return_msg = MapUtils.getString("return_msg", resultUn);
			//
			if (return_code.equalsIgnoreCase("FAIL")) {
				return new CommonResult().failed("支付失败," + return_msg);
			} else if (return_code.equalsIgnoreCase("SUCCESS")) {
				// 返回数据
				String result_code = MapUtils.getString("result_code", resultUn);
				String err_code_des = MapUtils.getString("err_code_des", resultUn);
				if (result_code.equalsIgnoreCase("FAIL")) {
					return new CommonResult().failed("支付失败," + err_code_des);
				} else if (result_code.equalsIgnoreCase("SUCCESS")) {
					String prepay_id = MapUtils.getString("prepay_id", resultUn);
					// 先生成paySign
					// 参考https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=7_7&index=5
					resultObj.put("appId", appletSet.getAppId());
					resultObj.put("timeStamp",
							DateUtils.timeToStr(System.currentTimeMillis() / 1000, DateUtils.DATE_TIME_PATTERN));
					resultObj.put("nonceStr", nonceStr);
					resultObj.put("package", "prepay_id=" + prepay_id);
					resultObj.put("signType", "MD5");
					String paySign = WechatUtil.arraySign(resultObj, appletSet.getPartnerKey());
					resultObj.put("paySign", paySign);
					// 业务处理
					orderInfo.setPrepayId(prepay_id);
					// 付款中
					orderInfo.setStatus(OrderStatus.INIT.getValue());
					orderInfo.setModifyTime(new Date());
					centerOrderRechargeMapper.updateById(orderInfo);

					OmsOrderOperateHistory history = new OmsOrderOperateHistory();
					history.setOrderId(orderInfo.getId());
					history.setCreateTime(new Date());
					history.setOperateMan("shop");
					history.setPreStatus(OrderStatus.INIT.getValue());
					history.setOrderStatus(OrderStatus.TO_DELIVER.getValue());
					history.setNote("小程序支付");
					orderOperateHistoryService.save(history);

					return ApiBaseAction.toResponsObject(200, "微信统一订单下单成功", resultObj);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			return new CommonResult().failed("支付失败,error=" + e.getMessage());
		}
		return new CommonResult().failed("支付失败");
	}

	@Override
	public void notify(HttpServletRequest request, HttpServletResponse response) {
		try {
			request.setCharacterEncoding("UTF-8");
			response.setCharacterEncoding("UTF-8");
			response.setContentType("text/html;charset=UTF-8");
			response.setHeader("Access-Control-Allow-Origin", "*");
			InputStream in = request.getInputStream();
			ByteArrayOutputStream out = new ByteArrayOutputStream();
			byte[] buffer = new byte[1024];
			int len = 0;
			while ((len = in.read(buffer)) != -1) {
				out.write(buffer, 0, len);
			}
			out.close();
			in.close();
			// xml数据
			String reponseXml = new String(out.toByteArray(), "utf-8");

			WechatRefundApiResult result = (WechatRefundApiResult) XmlUtil.xmlStrToBean(reponseXml,
					WechatRefundApiResult.class);
			String result_code = result.getResult_code();
			// 订单编号
			String out_trade_no = result.getOut_trade_no();
			log.error("订单" + out_trade_no + "支付成功");
			// 业务处理
			if (result_code.equalsIgnoreCase("FAIL")) {
				log.error("订单" + out_trade_no + "支付失败");
				response.getWriter().write(setXml("SUCCESS", "OK"));
			} else if (result_code.equalsIgnoreCase("SUCCESS")) { 
				 // 支付成功
				CenterOrderRecharge orderInfo = centerOrderRechargeMapper.selectOne(new QueryWrapper<CenterOrderRecharge>().eq("order_sn", out_trade_no));
				orderInfo.setStatus(OrderStatus.TRADE_SUCCESS.getValue());
				orderInfo.setPaymentTime(new Date());
				orderInfo.setModifyTime(new Date());
				centerOrderRechargeMapper.updateById(orderInfo);
				BigDecimal giveAmount = BigDecimal.ZERO;
				boolean giveAmountFlag = false;
				if (orderInfo.getGiveAmount() != null && orderInfo.getGiveAmount().compareTo(BigDecimal.ZERO) > 0) {
					giveAmount = orderInfo.getGiveAmount();
					giveAmountFlag = true;
				}
				// centerJifen
				CenterJifen centerJifen = centerJifenService.selectCenterJifenById(orderInfo.getMemberId());
				if (null != centerJifen) {
					Double money = centerJifen.getMoney();
					if (null == money) {
						money = 0.0d;
					}
					// centerItem
					CenterItem centerItem = new CenterItem();
					centerItem.setUserId(orderInfo.getMemberId());
					centerItem.setName("余额充值");
					centerItem.setTime(new Date());
					centerItem.setIncome(orderInfo.getPayAmount().doubleValue());
					centerItem.setType(2);
					centerItem.setStoreId(0);
					centerItemService.insertCenterItem(centerItem);
					if (giveAmountFlag) {
						CenterItem giveCenterItem = new CenterItem();
						giveCenterItem.setUserId(orderInfo.getMemberId());
						giveCenterItem.setName("余额充值赠送");
						giveCenterItem.setTime(new Date());
						giveCenterItem.setIncome(orderInfo.getGiveAmount().doubleValue());
						giveCenterItem.setType(2);
						giveCenterItem.setStoreId(0);
						centerItemService.insertCenterItem(giveCenterItem);
					}

					centerJifen.setMoney(orderInfo.getPayAmount().add(giveAmount).add(new BigDecimal(money.toString()))
							.doubleValue());
					centerJifenService.updateById(centerJifen);
				}
				// umsMember
				UmsMember member = memberService.getById(orderInfo.getMemberId());
				if (null != member) {
					BigDecimal blance = member.getBlance();
					if (null == blance) {
						blance = BigDecimal.ZERO;
					}
					// UmsMemberBlanceLogService
					UmsMemberBlanceLog blog = new UmsMemberBlanceLog();
					blog.setMemberId(member.getId());
					blog.setCreateTime(new Date());
					blog.setNote("余额充值：" + orderInfo.getPayAmount());
					blog.setPrice(member.getBlance());
					blog.setType(AllEnum.BlanceType.ADD.code());
					blog.setStoreId(0);
					blanceLogService.save(blog);
					if (giveAmountFlag) {
						UmsMemberBlanceLog blog1 = new UmsMemberBlanceLog();
						blog1.setMemberId(member.getId());
						blog1.setCreateTime(new Date());
						blog1.setNote("余额充值赠送：" + orderInfo.getGiveAmount());
						blog1.setPrice(member.getBlance());
						blog1.setType(AllEnum.BlanceType.ADD.code());
						blog1.setStoreId(0);
						blanceLogService.save(blog1);
						giveAmount = orderInfo.getGiveAmount();
					}

					member.setBlance(orderInfo.getPayAmount().add(giveAmount).add(blance));
					memberService.updateById(member);
				}
			
			
				response.getWriter().write(setXml("SUCCESS", "OK"));
			}
		} catch (Exception e) {
			e.printStackTrace();
			return;
		}
	}

	// 返回微信服务
	public static String setXml(String return_code, String return_msg) {
		return "<xml><return_code><![CDATA[" + return_code + "]]></return_code><return_msg><![CDATA[" + return_msg
				+ "]]></return_msg></xml>";
	}

}
